import re

from django.conf import settings
from django_redis import get_redis_connection
from rest_framework import serializers
from itsdangerous import TimedJSONWebSignatureSerializer as TJS

from oauth.models import OAuthQQUser
from users.models import User


class OauthSerializer(serializers.ModelSerializer):
    # user_id,token 字段因为需要返回，所以构造
    user_id = serializers.IntegerField(read_only=True)
    token = serializers.CharField(read_only=True)

    access_token = serializers.CharField(write_only=True)

    sms_code = serializers.CharField(write_only=True,max_length=6,min_length=6)
    mobile = serializers.CharField(max_length=11)

    class Meta:
        model = User
        fields = ("mobile","password","sms_code","token","user_id","username","access_token")
        extra_kwargs ={
            "password":{
                "write_only":True
            },
            "username":{
                "read_only":True
            }
        }

    # 验证手机号格式
    def validate_mobile(self, value):
        if not re.match(r"^1[3-9]\d{9}$", value):
            raise serializers.ValidationError("手机号格式不正确")

        return value

    # 短信验证码验证
    def validate(self, attrs):
        # 验证access_token
        # 解密
        tjs = TJS(settings.SECRET_KEY,300)
        try:
            data = tjs.loads(attrs["access_token"])
        except:
            raise  serializers.ValidationError("无效的access_token")
        # 因为后端绑定需要用openid ，所以需要获取字典中的值openid
        openid = data.get("openid")

        attrs["openid"] = openid

        # 短信验证码验证
        # 通过手机号获取redis 存储的短信验证码
        # 比较两个验证码是否正确
        coon = get_redis_connection("sms_code")
        real_sms_code = coon.get("sms_code_%s" % attrs["mobile"])
        # 这个短信验证码是二进制数据
        if not real_sms_code:
            raise serializers.ValidationError("短信验证码失效")

        if real_sms_code.decode() != attrs["sms_code"]:
            raise serializers.ValidationError("短信验证码不正确")



        # 判断用户手机号是否注册过
        try:
            user = User.objects.get(mobile=attrs["mobile"])

        except:
            # 没有注册过，注册为新用户
            return  attrs
        else:
            # 注册过，查询用户进行绑定
            # 判断密码
            if not user.check_password(attrs["password"]):
                raise serializers.ValidationError("密码错误")

            attrs["user"] = user
            return attrs

    def create(self, validated_data):
        # 由于validated_data 是attrs ，attrs是前段发送的数据，没有user,所以需要
        # OAuthQQUser.objects.create(users = validated_data["users"],openid = validated_data["openid"])
        # 需要判断用户，判断是注册过的用户，还是没有注册过的用户
        user = validated_data.get("user",None)
        if not user:
            # 如果没有注册过，创建用户
            user = User.objects.create_user(username=validated_data["mobile"],password=validated_data["password"],mobile = validated_data["mobile"])

        # 进行用户绑定
        OAuthQQUser.objects.create(user=user,openid = validated_data["openid"])

        # 返回的user 中没有token 值，所以需要创建token值
        # 手动创建令牌
        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        # 生成载荷部分
        payload = jwt_payload_handler(user)
        # 生成tocken
        token = jwt_encode_handler(payload)
        # 对对象添加属性
        user.token = token
        user.user_id = user.id

        return user
